package ext.tianma.part.forms;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Vector;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import wt.doc.WTDocument;
import wt.doc.WTDocumentMaster;
import wt.fc.ObjectVector;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.fc.WTObject;
import wt.introspection.WTIntrospector;
import wt.method.RemoteAccess;
import wt.part.QuantityUnit;
import wt.part.WTPart;
import wt.part.WTPartDescribeLink;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartReferenceLink;
import wt.part.WTPartUsageLink;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionHelper;
import wt.util.WTException;
import wt.util.WTInvalidParameterException;
import wt.util.WTMessage;
import wt.util.WTProperties;
import wt.util.WTPropertyVetoException;
import wt.vc.views.View;
import wt.vc.views.ViewHelper;
import wt.vc.wip.WorkInProgressHelper;
import wt.workflow.engine.WfEngineHelper;

import com.ptc.cipjava.intdict;
import com.ptc.core.components.beans.ObjectBean;
import com.ptc.core.components.forms.DefaultObjectFormProcessor;
import com.ptc.core.components.forms.FormProcessingStatus;
import com.ptc.core.components.forms.FormResult;
import com.ptc.core.components.util.FeedbackMessage;
import com.ptc.core.ui.resources.FeedbackType;
import com.ptc.netmarkets.model.NmOid;
import com.ptc.netmarkets.util.beans.NmCommandBean;

import ext.com.core.CoreUtil;
import ext.com.iba.IBAUtil;
import ext.generic.part.CusIBAUtil;
import ext.tianma.bom.workflow.BOMBusinessUtil;
import ext.tianma.bom.workflow.SingletonBOM;
import ext.tianma.part.PartCommands;
import ext.tianma.workflow.workflowCommands;

public class VersionPromoteProcessor extends DefaultObjectFormProcessor implements RemoteAccess, Serializable{
	private static boolean VERBOSE = false;
    private static String CLASSNAME = VersionPromoteProcessor.class.getName();
    private static final String RESOURCE = "ext.tianma.resource.ResourceRB";
    //物料生效地
  	private static final String PART_NUMBER_EFFECTIVE_SITE = "partNumberEffectiveSite" ;
  	private static final String VIEW_A20 = "A20" ;
  	private static final String VIEW_C06 = "C06" ;
    private static String materialExcelPath = "" ;
	public static WTProperties wtProperties = null ;
	//原材料类型
	public static final String RAWMATERIAL = SingletonBOM.getInstance().getRawMaterial();
    static
    {
        try
        {
            WTProperties wtproperties = WTProperties.getLocalProperties();
            VERBOSE = wtproperties.getProperty("ext.tianma.part.verbose", false);
            
            wtProperties = WTProperties.getLocalProperties();
            materialExcelPath = wtProperties.getProperty("ext.tianma.part.materials");
        }
        catch (Throwable throwable)
        {
            throwable.printStackTrace(System.err);
            throw new ExceptionInInitializerError(throwable);
        }
    }
	@Override
	public FormResult doOperation(NmCommandBean arg0, List<ObjectBean> arg1) throws WTException {
		FormResult formresult = new FormResult();
		formresult.setStatus(FormProcessingStatus.SUCCESS);
	
		NmOid nmoid = arg0.getActionOid();
		WTPart currentPart = (WTPart) nmoid.getRefObject();
		if( currentPart != null ){
			if( WorkInProgressHelper.isCheckedOut(currentPart) ){
				throw new WTException( "零部件被检出，不能进行版本进阶。" );
			}
		}
		String number = currentPart.getNumber();
		System.out.println("Debug  版本进阶   当前进阶的物料编号："+currentPart.getNumber());
		String softType = IBAUtil.getSoftType(currentPart).getLogicalIdentifier();
		softType = softType.substring(softType.indexOf(".")+1);
		Locale locale = SessionHelper.getLocale();
		if(softType.equals("C4")&&number.endsWith("K"))
		{
			String message=WTMessage.getLocalizedMessage(RESOURCE,"PROMOTE_ERR",null,locale);
			throw new WTException(message);
		}
		WTPart newPart  = null;
		try {
			newPart = PartCommands.saveNewPart(currentPart);
		} catch (WTPropertyVetoException e) {
			// TODO Auto-generated catch block
			throw new WTException(e.toString());
		}
		System.out.println("Debug  版本进阶  另存为的物料编号："+newPart.getNumber());
		
		/**
		 * @author xuge_ning
		 * @reason处理历史数据问题，进阶时不再使用A20视图，C06视图
		 */
		try {
			Vector partNumberEffectiveSite = IBAUtil.getIBAValue2(newPart, PART_NUMBER_EFFECTIVE_SITE);
			View[] allViews = ViewHelper.service.getAllViews();
			System.out.println("Debug  版本进阶视图allViews：" + allViews.toString());
			if(partNumberEffectiveSite != null){
				String updatePartNumberEffectiveSite = "";
				for (int i = 0; i < partNumberEffectiveSite.size(); i++) {
					Object obj = partNumberEffectiveSite.get(i);
					if( obj != null && obj instanceof String ){
						System.out.println("Debug  版本进阶料号生效地" +  obj.toString());
						if(!VIEW_A20.equals((String)obj) && !VIEW_C06.equals((String)obj)){
							if("".equals(updatePartNumberEffectiveSite)){
								updatePartNumberEffectiveSite = (String) obj;
							} else{
								updatePartNumberEffectiveSite = updatePartNumberEffectiveSite + "," + (String) obj;
							}
						}
						
						System.out.println("Debug  版本进阶料号生效地总汇" +  updatePartNumberEffectiveSite);
					}
				}
				CusIBAUtil.forceSetEnumIBAValue( newPart , PART_NUMBER_EFFECTIVE_SITE , updatePartNumberEffectiveSite );
			}
		} catch (RemoteException e1) {
			e1.printStackTrace();
		}
		
		
		//删除使用关系
		Vector usagelinks2 =  CoreUtil.getPartUsageLinks(newPart);                
        for(int c = 0; c < usagelinks2.size(); c++)
        {
            WTPartUsageLink usagelink = (WTPartUsageLink)usagelinks2.elementAt(c);
            PersistenceServerHelper.manager.remove(usagelink); 
        }
       // WfEngineHelper.service.TerminateObjectsRunningWorkflows((LifeCycleManaged)newPart);

   
        
        
        
        
        //删除描述关系
        QueryResult desclinks = WTPartHelper.service.getDescribedByDocuments(newPart);
        while(null!=desclinks&&desclinks.hasMoreElements())
        {
        	WTDocument doc = (WTDocument) desclinks.nextElement();
        	System.out.println("Debug 版本进阶   描述文档 的名称： "+doc.getName());
        	WTPartDescribeLink link = getDescribeLinkBetweenPartAndDoc(newPart, doc);
        	 PersistenceServerHelper.manager.remove(link); 
        }
        
        //删除参考关系
        QueryResult reflinks = CoreUtil.getAssociatedReferenceDocuments(newPart);
        
        while(null!=reflinks&&reflinks.hasMoreElements())
        {
        	WTDocument doc = (WTDocument) reflinks.nextElement();
        	System.out.println("Debug 版本进阶   参考文档 的名称： "+doc.getName());
        	WTPartReferenceLink link = getReferenceLinkBetweenPartAndDoc(newPart, doc);
        	 PersistenceServerHelper.manager.remove(link); 
        }
        
        
        WfEngineHelper.service.terminateObjectsRunningWorkflows(newPart);
        
        try {
			workflowCommands.startVersionPromoteWorkFlow(newPart);
		} catch (WTPropertyVetoException e) {
			// TODO Auto-generated catch block
			throw new WTException(e.toString());
		}
		
		//更新零部件默认单位
        try {
			String value=(String) IBAUtil.getIBAValue( newPart , "partEName");
			String unit=PartUtil.getRawMaterialsUnit(getWorkbook( materialExcelPath ).getSheetAt(1), value);
			changePartUnit( newPart , unit);
			 String whetherPartRecognize=(String) IBAUtil.getIBAValue( newPart , "whetherPartRecognize");
			 System.out.println("whetherPartRecognize====>>"+whetherPartRecognize);
			 if("是".equals(whetherPartRecognize)) {
				 Hashtable<String, String> values = new Hashtable<String, String>();
				 values = addToHashtable(values,"whetherPartRecognize","否");
				 System.out.println("values===>>"+values);
				 IBAUtil.setSoftTypeIBAValues(newPart, values);
				 newPart=(WTPart)PersistenceHelper.manager.save(newPart);
				 System.out.println("==样品承认设置成功=="+values);
			 }
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		
        
        //更新原材料是否样品承认属性默认为否
		/*
		 * String whetherPartRecognize=""; try { whetherPartRecognize = ((String)
		 * IBAUtil.getIBAValue(currentPart, "whetherPartRecognize")).trim();
		 * System.out.println("==进阶前物料的样品承认的值whetherPartRecognize=="+
		 * whetherPartRecognize); BOMBusinessUtil.isSubObject(newPart, RAWMATERIAL) if()
		 * {
		 * 
		 * } } catch (RemoteException e) { // TODO Auto-generated catch block
		 * e.printStackTrace(); }
		 */
        
       
        
		FeedbackMessage feedbackmessage = new FeedbackMessage(
				FeedbackType.SUCCESS, null, "版本进阶流程启动成功", null, new String[] {});
		formresult.addFeedbackMessage(feedbackmessage);
		return formresult;
	}
	/**
	 * 实现Hashtable添加数据时不会出现空指针异常
	 * 
	 * @param hashtable
	 * @param key
	 * @param value
	 * @return
	 */
	private static Hashtable<String, String> addToHashtable(Hashtable<String, String> hashtable, String key,
			String value) {
		if (key == null && hashtable != null) {
			return hashtable;
		}

		if (value == null && hashtable != null) {
			return hashtable;
		}

		if (key == null && hashtable == null) {
			return new Hashtable<String, String>();
		}

		if (value == null && hashtable == null) {
			return new Hashtable<String, String>();
		}

		if (hashtable == null) {
			hashtable = new Hashtable<String, String>();
		}
		hashtable.put(key, value);

		return hashtable;
	}

	public static QueryResult getAssociations(WTPart wtpart)
			throws WTException
		{
			String s1 = null;
			String s2 = null;
			
			if(WTIntrospector.getLinkInfo(wt.part.WTPartReferenceLink.class).isRoleA("describedBy"))
			{
				s1 = "roleAObjectRef.key";
				s2 = "roleBObjectRef.key";
			} 
			else
			{
				s2 = "roleAObjectRef.key";
				s1 = "roleBObjectRef.key";
			}
			QuerySpec queryspec1 = new QuerySpec(wt.part.WTPartDescribeLink.class);
			queryspec1.appendClassList(wt.doc.WTDocument.class, true);
			queryspec1.appendWhere(new SearchCondition(wt.part.WTPartDescribeLink.class, s2, "=", PersistenceHelper.getObjectIdentifier(wtpart)), 0, 0);
			/*queryspec1.appendAnd();
			queryspec1.appendWhere(new SearchCondition(wt.part.WTPartDescribeLink.class, s1 + "." + "id", wt.doc.WTDocument.class, "thePersistInfo.theObjectIdentifier.id"), 0, 1);
			queryspec1.appendAnd();
			queryspec1.appendWhere(new SearchCondition(wt.doc.WTDocument.class, "masterReference.key", "=", PersistenceHelper.getObjectIdentifier(wtdocument.getMaster())), 1, 1);*/
			//QueryResult queryresult = PersistenceServerHelper.manager.query(queryspec1);
			QueryResult queryresult = PersistenceHelper.manager.find(queryspec1);
			
			ObjectVector objectvector = new ObjectVector();
			/*WTPartDescribeLink wtpartdescribelink;
			
			for(; queryresult.hasMoreElements(); objectvector.addElement(wtpartdescribelink))
			{
				Object aobj[] = (Object[])queryresult.nextElement();
				wtpartdescribelink = (WTPartDescribeLink)aobj[0];
				try
				{
					wtpartdescribelink.setDescribes(wtpart);
					wtpartdescribelink.setDescribedBy((WTDocument)aobj[1]);
				}
				catch(WTPropertyVetoException wpve)
				{
					throw new WTException(wpve);
				}
			}*/
			
			//get WTPartReferenceLink
			/*String s = (WTIntrospector.getLinkInfo(wt.part.WTPartReferenceLink.class).isRoleA("references") ? "roleAObjectRef" : "roleBObjectRef") + "." + "key";
			QuerySpec queryspec = new QuerySpec(wt.doc.WTDocumentMaster.class, wt.part.WTPartReferenceLink.class);
			queryspec.appendWhere(new SearchCondition(wt.part.WTPartReferenceLink.class, s, "=", PersistenceHelper.getObjectIdentifier(wtdocument.getMaster())), 1, 1);
			//QueryResult queryresult2= PersistenceServerHelper.manager.expand(wtpart, "references", queryspec, false);
			QueryResult queryresult2 = PersistenceHelper.manager.navigate(wtpart, "references", queryspec, false);
			
			while(queryresult2.hasMoreElements())
			{
				objectvector.addElement(queryresult2.nextElement());
			}
			return new QueryResult(objectvector);*/
			return queryresult;
		}	
	
	public static QueryResult getRefernce(WTPart wtpart)
			throws WTException
		{
			String s1 = null;
			String s2 = null;
			
			if(WTIntrospector.getLinkInfo(wt.part.WTPartReferenceLink.class).isRoleA("describedBy"))
			{
				s1 = "roleAObjectRef.key";
				s2 = "roleBObjectRef.key";
			} 
			else
			{
				s2 = "roleAObjectRef.key";
				s1 = "roleBObjectRef.key";
			}
			QuerySpec queryspec1 = new QuerySpec(wt.part.WTPartReferenceLink.class);
			queryspec1.appendClassList(wt.doc.WTDocument.class, true);
			queryspec1.appendWhere(new SearchCondition(wt.part.WTPartReferenceLink.class, s2, "=", PersistenceHelper.getObjectIdentifier(wtpart)), 0, 0);
			/*queryspec1.appendAnd();
			queryspec1.appendWhere(new SearchCondition(wt.part.WTPartDescribeLink.class, s1 + "." + "id", wt.doc.WTDocument.class, "thePersistInfo.theObjectIdentifier.id"), 0, 1);
			queryspec1.appendAnd();
			queryspec1.appendWhere(new SearchCondition(wt.doc.WTDocument.class, "masterReference.key", "=", PersistenceHelper.getObjectIdentifier(wtdocument.getMaster())), 1, 1);*/
			//QueryResult queryresult = PersistenceServerHelper.manager.query(queryspec1);
			QueryResult queryresult = PersistenceHelper.manager.find(queryspec1);
			
			ObjectVector objectvector = new ObjectVector();
			/*WTPartDescribeLink wtpartdescribelink;
			
			for(; queryresult.hasMoreElements(); objectvector.addElement(wtpartdescribelink))
			{
				Object aobj[] = (Object[])queryresult.nextElement();
				wtpartdescribelink = (WTPartDescribeLink)aobj[0];
				try
				{
					wtpartdescribelink.setDescribes(wtpart);
					wtpartdescribelink.setDescribedBy((WTDocument)aobj[1]);
				}
				catch(WTPropertyVetoException wpve)
				{
					throw new WTException(wpve);
				}
			}*/
			
			//get WTPartReferenceLink
			/*String s = (WTIntrospector.getLinkInfo(wt.part.WTPartReferenceLink.class).isRoleA("references") ? "roleAObjectRef" : "roleBObjectRef") + "." + "key";
			QuerySpec queryspec = new QuerySpec(wt.doc.WTDocumentMaster.class, wt.part.WTPartReferenceLink.class);
			queryspec.appendWhere(new SearchCondition(wt.part.WTPartReferenceLink.class, s, "=", PersistenceHelper.getObjectIdentifier(wtdocument.getMaster())), 1, 1);
			//QueryResult queryresult2= PersistenceServerHelper.manager.expand(wtpart, "references", queryspec, false);
			QueryResult queryresult2 = PersistenceHelper.manager.navigate(wtpart, "references", queryspec, false);
			
			while(queryresult2.hasMoreElements())
			{
				objectvector.addElement(queryresult2.nextElement());
			}
			return new QueryResult(objectvector);*/
			return queryresult;
		}	
	
	/**
	 * 获取零部件与文档的描述类的关联关系（WTPartDescribeLink）
	 * @param part 想要获取关联关系的零部件
	 * @param document 想要获取关联关系的文档
	 * @return 返回关联关系列表，如果零部件或文档不存在，返回空
	 * <br><br>
	 * <b>getDescribeLinkBetweenPartAndDoc</b>
	 * <br><b>Rev:</b> 1.0 - 2006/03/21, kan
	 * <br><b>Comment:</b> 根据零部件得到描述的关联关系，然后根据关系得到文档，最后文档进行比较。
	 */
	public static WTPartDescribeLink getDescribeLinkBetweenPartAndDoc(WTPart part, WTDocument document)
		throws WTException
	{
		//首先判断输入参数的有效性
		if	(part==null || document==null)
			return null;					
		
		//用于存放WTPartDescribeLink的连接关系
		Vector docLinkV= new Vector();
		
		//得到和当前零件关联的文档的描述关系WTPartDescribeLink
		QueryResult qr= WTPartHelper.service.getDescribedByWTDocuments(part, false);     
		if(qr != null && qr.hasMoreElements())
		{
			while(qr.hasMoreElements())
			{
				//将对象添加到
				WTObject obj= (WTObject)qr.nextElement();
				docLinkV.addElement(obj);
			}
		}
		
		//遍历整个关联关系的列表，进行比较
		if((docLinkV!=null) && (docLinkV.size()>0))
		{
			for(int i=0; i<docLinkV.size(); i++)
			{
				WTPartDescribeLink describeLink= (WTPartDescribeLink)docLinkV.elementAt(i);
				WTDocument doc= (WTDocument) describeLink.getDescribedBy();
				//比较文档是不是相同，如果相同的话，返回WTPartDescribeLink
				if(PersistenceHelper.isEquivalent(doc, document))
					return describeLink;
			}
		}
		return null;
	}
	
	
	/**
	 * 获取零部件与文档的参考类的关联关系（WTPartReferenceLink）
	 * @param part 想要获取关联关系的零部件
	 * @param document 想要获取关联关系的文档
	 * @return 返回关联关系列表，如果零部件或文档不存在，返回空。
	 * <br><br>
	 * <b>getReferenceLinkBetweenPartAndDoc</b>
	 * <br><b>Rev:</b> 1.0 - 2006/03/21, kan
	 * <br><b>Comment:</b> 
	 */
	public static WTPartReferenceLink getReferenceLinkBetweenPartAndDoc(WTPart part, WTDocument document)
		throws WTException
	{
		//首先判断输入参数的有效性
		if	(part==null || document==null)
			return null;					
		
		//得到document的编码
		String docnumber =document.getNumber();
		
		//遍历所有的WTPartReferenceLink，根据doc的编码判断是不是需要的link
		QueryResult qr= PersistenceHelper.manager.navigate(part, "references", WTPartReferenceLink.class, false);        
		while(qr !=null && qr.hasMoreElements())
		{
			//得到link
			WTPartReferenceLink link = (WTPartReferenceLink)qr.nextElement();
			
			//得到link的docmaster
			WTDocumentMaster docmaster =(WTDocumentMaster)link.getReferences();
			
			//得到master的number
			String docmasternumber =docmaster.getNumber();
			
			//判断是不是需要的link,如果相等,返回link
			if (docmasternumber.compareToIgnoreCase(docnumber)==0)
				return link;
		}
		return null; 
	}
	
	/**
	 * 修改零部件的默认单位
	 * 
	 * @param part
	 * @param unit
	 */
	public static void changePartUnit(WTPart part , String unit){
		if( part == null ){
			System.out.println(">>>>> 设置单位, part == null");
			return ;
		}
		
		if( unit == null || unit.equals("")){
			System.out.println(">>>>> 设置单位, unit == null");
			return ;
		}
		
		QuantityUnit quantityUnit = QuantityUnit.toQuantityUnit(unit);
		
		if( quantityUnit != null ) {			
			WTPartMaster partMaster = (WTPartMaster)part.getMaster() ;
			
			try{
				System.out.println(">>>>> 开始设置单位！");
				
				//更新单位
				partMaster.setDefaultUnit( quantityUnit );
				partMaster = (WTPartMaster)PersistenceHelper.manager.save( partMaster ); 
				
				System.out.println(">>>>> 设置单位成功！");
			} catch (WTInvalidParameterException e) {
				e.printStackTrace();
			} catch (WTPropertyVetoException e) {
				e.printStackTrace();
			} catch (WTException e) {
				e.printStackTrace();
			}
		}else{
			System.out.println(">>>>> 设置单位, 单位为空." + unit + " 不能转换为单位.");
		}
	}

	public static Workbook getWorkbook(String path){
		Workbook  workbook = null;
		
		InputStream in = null;
		
		try {
			in = new FileInputStream(path);
			
			workbook = WorkbookFactory.create(in);
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (InvalidFormatException e) {
			e.printStackTrace();
		} finally{
			closeStream(in);
			
			if( workbook == null ){
				System.out.println(">>>>> Can't get Excel Workbook by excel file path : " + path ) ;
			}
		}
		
		return workbook ;
	}
	
	public static void closeStream(InputStream in) {
		if( in != null ){
			try {
				in.close() ;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
